package main

import (
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
)

// NewProxy takes target host and creates a revers proxy
// NewProxy 拿到targetHost 后， 创建一个反向代理
func NewProxy(targetHost string) (*httputil.ReverseProxy, error) {
	url, err := url.Parse(targetHost)
	if err != nil {
		return nil, err
	}
	// 注册代理响应的各个函数
	proxy := httputil.NewSingleHostReverseProxy(url)

	originalDirector := proxy.Director
	proxy.Director = func(r *http.Request) {
		originalDirector(r)
		modifyRequest(r)
	}

	proxy.ModifyResponse = modifyResponse()
	proxy.ErrorHandler = errorHandler()
	return proxy, nil
}

func modifyRequest(req *http.Request) {
	req.Header.Set("X-Proxy", "Simple-Reverse-proxy")
}

// proxyRequestHandler handles the http request using proxy
// proxyRequesthandler 使用 proxy 处理请求
// 代理请求函数
func ProxyRequestHandler(proxy *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
	return func(rw http.ResponseWriter, r *http.Request) {
		proxy.ServeHTTP(rw, r)
	}
}

// 修改响应的函数
func modifyResponse() func(*http.Response) error {
	return func(r *http.Response) error {
		r.Header.Set("x-Proxy", "Magical")
		return nil
	}
}

// 注册失败的响应函数（如果在代理过程中失败了，则会自动调用此函数）
func errorHandler() func(http.ResponseWriter, *http.Request, error) {
	return func(rw http.ResponseWriter, r *http.Request, e error) {

	}
}

func main() {
	// initialize a reverse proxy and pass the actual backend server url here
	// 初始化反向代理并传入需要处理的真正的后端地址
	proxy, err := NewProxy("http://localhost:9528")
	if err != nil {
		panic(err)
	}
	// handle all request to your server using the proxy
	//  使用 proxy 处理所有的请求到你的服务器
	http.HandleFunc("/", ProxyRequestHandler(proxy))
	log.Fatal(http.ListenAndServe(":8080", nil))
}
